﻿using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using DotNetOpenAuth.OpenId.RelyingParty;
using octalforty.Componento.Web.Models;
using octalforty.Componento.Web.Shared.Data;

namespace octalforty.Componento.Web.Controllers
{
    [HandleError]
    public class ProfileController : Controller
    {
        [Authorize()]
        public ActionResult Index()
        {
            using(var dataContext = new ComponentoDataContext())
            {
                var profile = (from p in dataContext.Profiles
                               where p.OpenID == User.Identity.Name
                               select p).FirstOrDefault();

                var model = new ProfileModel { Email = profile.Email, Name = profile.Name };
                return View(model);
            } // using
        }

        [Authorize()]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Save(string name, string email)
        {
            using(var dataContext = new ComponentoDataContext())
            {
                var profile = (from p in dataContext.Profiles
                               where p.OpenID == User.Identity.Name
                               select p).FirstOrDefault();

                profile.Name = name;
                profile.Email = email;

                dataContext.SubmitChanges();
            } // using

            return RedirectToAction("Index");
        }

        public ActionResult Login()
        {
            var openId = new OpenIdRelyingParty();
            var authenticationResponse = openId.GetResponse();

            if(authenticationResponse != null)
            {
                switch(authenticationResponse.Status)
                {
                    case AuthenticationStatus.Authenticated:

                        using(var dataContext = new ComponentoDataContext())
                        {
                            var openIdIdentifier = (string)authenticationResponse.ClaimedIdentifier;
                            var profile = (from p in dataContext.Profiles
                                           where p.OpenID == openIdIdentifier
                                           select p).FirstOrDefault();

                            if(profile == null)
                            {
                                var claimsResponse = authenticationResponse.GetExtension<ClaimsResponse>();

                                profile = new Profile
                                    {
                                        Name = claimsResponse == null || string.IsNullOrEmpty(claimsResponse.Nickname) ?
                                            openIdIdentifier :
                                            claimsResponse.Nickname,
                                        Email = claimsResponse == null || string.IsNullOrEmpty(claimsResponse.Email) ?
                                            "" :
                                            claimsResponse.Email,
                                        OpenID = openIdIdentifier
                                    };

                                dataContext.Profiles.InsertOnSubmit(profile);
                                dataContext.SubmitChanges();
                            } // if
                        } // using

                        FormsAuthentication.RedirectFromLoginPage(authenticationResponse.ClaimedIdentifier, false);
                        break;
                    case AuthenticationStatus.Canceled:
                        ModelState.AddModelError("openIdIdentifier",
                            "Login was cancelled at the provider");
                        break;
                    case AuthenticationStatus.Failed:
                        ModelState.AddModelError("openIdIdentifier",
                            "Login failed using the provided OpenID identifier");
                        break;
                } // switch
            } // if
             
            return View();
        }

        [ValidateInput(false)]
        [AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Login(string openIdIdentifier) 
        {
            if(!Identifier.IsValid(openIdIdentifier))
            {
                ModelState.AddModelError("openIdIdentifier", "The specified login identifier is invalid");
                return View("Login");
            } // if

            var openId = new OpenIdRelyingParty();
            var request = openId.CreateRequest(openIdIdentifier);

            request.AddExtension(new ClaimsRequest
                {
                    Email = DemandLevel.Require,
                    Nickname = DemandLevel.Require,
                });

            return request.RedirectingResponse.AsActionResult();
		}
    }
}
